home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / CodeWarrior Lite / Metrowerks C⁄C++ Lite / Headers / System Extras Headers / GX Graphics Libraries / graphicsBug library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-17  |  8.2 KB  |  206 lines  |  [TEXT/MMCC]

  1. /* graphics libraries:
  2.     general library routines    
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1993 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6. /* this is so that we get the trap version of Gestalt */
  7. #ifndef SystemSevenOrLater
  8.     #define SystemSevenOrLater 1
  9. #endif
  10.     
  11. #include <GestaltEqu.h>
  12. #include <Processes.h>
  13. #include "math types.h"
  14. #include "graphics debugging.h"
  15. #include "graphicsBug library.h"
  16.  
  17.  
  18. // *** eventually, allow this to work both locally and over the network?
  19. // *** for remote debugging, lauch gBug on remote machine, and then use special menu item
  20. // to bring up PPCToolbox browser. Select one or more machines running graphics init to receive 
  21. // errors from, or to set break points, etc.
  22.  
  23. boolean SendMessageToGraphicsBug(long command, const char *string, unsigned long message, boolean waitForCompletion)
  24. {
  25.     ProcessSerialNumber     skiaBugProcess;
  26.     OSErr               err;
  27.     struct graphicsBugParameters *blockPointer = nil;
  28.     EventRecord         theEvent;
  29.     
  30.     {   LaunchParamBlockRec     launch;
  31.         DTPBRec             bugAp;
  32.         FSSpec              fileSpecification;
  33.         
  34.         bugAp.ioNamePtr = nil;
  35.         bugAp.ioVRefNum = 0;
  36.         if ((err = PBDTGetPath(&bugAp)) != 0)
  37.             return false; /* error */
  38.         bugAp.ioNamePtr = fileSpecification.name;
  39.         bugAp.ioCompletion = nil;
  40.         bugAp.ioIndex = 0;
  41.         bugAp.ioFileCreator = creatorType;
  42.         err = PBDTGetAPPLSync(&bugAp);
  43.         if (err)
  44.             return false; /* error */
  45.         /* is the file already launched ? */
  46.         {   ProcessInfoRec processInfo;
  47.             FSSpec processSpec;
  48.             
  49.             processInfo.processName = nil;
  50.             processInfo.processAppSpec = &processSpec;
  51.             processInfo.processInfoLength = sizeof(processInfo);
  52.             skiaBugProcess.highLongOfPSN = 0;
  53.             skiaBugProcess.lowLongOfPSN = kNoProcess;
  54.             while (GetNextProcess(&skiaBugProcess) == noErr) {
  55.                 if (GetProcessInformation(&skiaBugProcess, &processInfo) == noErr &&
  56.                     processInfo.processType == 'APPL' &&
  57.                     processInfo.processSignature == creatorType &&
  58.                     processInfo.processAppSpec->parID == bugAp.ioAPPLParID)
  59.                 {
  60.                     goto doEvent;
  61.                 }
  62.             }
  63.         }
  64.         launch.launchBlockID = extendedBlock;
  65.         launch.launchEPBLength = extendedBlockLen;
  66.         launch.launchFileFlags = 0;
  67.         launch.launchControlFlags = launchDontSwitch | launchContinue | launchNoFileFlags;
  68.         fileSpecification.vRefNum = 0;
  69.         fileSpecification.parID = bugAp.ioAPPLParID;
  70.         launch.launchAppSpec = &fileSpecification;
  71.         launch.launchAppParameters = nil;
  72.         err = LaunchApplication(&launch);
  73.         if (err)
  74.             return false; /* error */
  75.         if (launch.launchMinimumSize)  /* ap not already open */
  76.         {   register short counter = 4;
  77.         
  78.             do
  79.                 WaitNextEvent(0, &theEvent, -1, nil);
  80.             while (--counter);
  81.         }
  82.         skiaBugProcess = launch.launchProcessSN;
  83.     }
  84. doEvent:
  85. #ifdef __APPLEEVENTS__
  86.     {   AEAddressDesc   targetAddress;
  87.         AppleEvent  theAppleEvent;
  88.         AppleEvent  replyEvent;
  89.     
  90.         err = AECreateDesc(typeProcessSerialNumber, (Ptr)&skiaBugProcess, sizeof(skiaBugProcess), &targetAddress);
  91.         err = AECreateAppleEvent(kCoreEventClass, kAEOpenApplication, &targetAddress, kAutoGenerateReturnID,
  92.             kAnyTransactionID, &theAppleEvent);
  93.         err = AESend(&theAppleEvent, &replyEvent, kAENoReply | kAECanInteract | kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil);
  94.         AEDisposeDesc(&theAppleEvent);
  95.         
  96.         //  select the bottom of the window just in case it was pointing to the top
  97.         err = AECreateAppleEvent(bugEventClass, selectBugWindowPartEvent, &targetAddress, kAutoGenerateReturnID,
  98.             kAnyTransactionID, &theAppleEvent);
  99.         {   boolean selectTop = false;
  100.             
  101.             err = AEPutParamPtr(&theAppleEvent, chooseWindowPartBoolean, keyDirectObject, (Ptr)&selectTop, sizeof(selectTop));
  102.         }
  103.         err = AESend(&theAppleEvent, &replyEvent, kAENoReply | kAECanInteract | kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil);
  104.         AEDisposeDesc(&theAppleEvent);
  105.         
  106.         // create a second event that contains the error message and paste it into the window
  107.         err = AECreateAppleEvent(bugEventClass, pasteBugTextEvent, &targetAddress, kAutoGenerateReturnID,
  108.             kAnyTransactionID, &theAppleEvent);
  109.         {   Str255 quoted;
  110.             long length = strlen(str);
  111.             unsigned char *quotePtr = quoted;
  112.             
  113.             *quotePtr++ = '"';
  114.             BlockMove(str, quotePtr, length);
  115.             quotePtr += length;
  116.             if (num)
  117.             {   register int digit;
  118.                 register int counter = 8;
  119.                 
  120.                 BlockMove(": 0", quotePtr, 3);
  121.                 quotePtr += 3;
  122.                 *quotePtr++ = 'X';
  123.                 do {
  124.                     num = num << 4 | num >> 28;
  125.                     digit = num & 0xf;
  126.                     *quotePtr++ = digit > '9' ? digit - '9' + 'A' - 1 : digit + '0';
  127.                 } while (--counter);
  128.             }
  129.             *quotePtr++ = '"';
  130.             *quotePtr++ = returnChar;
  131.             err = AEPutParamPtr(&theAppleEvent, errorString, keyDirectObject, (Ptr) quoted, quotePtr - quoted);
  132.         }
  133.         err = AESend(&theAppleEvent, &replyEvent, kAEWaitReply | kAECanInteract | kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil);
  134.         AEDisposeDesc(&theAppleEvent);
  135.         AEDisposeDesc(&targetAddress);
  136.     }
  137. #else
  138.     {
  139.         if (GXGetGraphicsBugParametersPointer(&blockPointer))
  140.         {   char lastToggle;
  141.             long idleCount = 0;
  142.             
  143.             while (blockPointer->status <= graphicsBugRunning) {
  144.                 if (lastToggle != blockPointer->toggle) {
  145.                     lastToggle = blockPointer->toggle;
  146.                     idleCount = 0;
  147.                 } else {
  148.                     idleCount++;
  149.                     if (idleCount > maximumIdle)
  150.                         return false; /* timed out */
  151.                 }
  152.                 EventAvail(everyEvent, &theEvent);
  153.             }
  154.             {   register char *destStringPtr = blockPointer->string;
  155.                 register const char *sourceStringPtr = string;
  156.                 static char requestChars[] = "nwe";
  157.                 
  158.                 blockPointer->message = message;
  159.                 if (command >= noticeMessage && command <= errorMessage) {
  160.                     *destStringPtr++ = 'g';
  161.                     *destStringPtr++ = requestChars[command];
  162.                 } else if (sourceStringPtr) {
  163.                     if (command == debugMessage)
  164.                         *destStringPtr++ = '"';
  165.                     while (*sourceStringPtr)
  166.                         *destStringPtr++ = *sourceStringPtr++;
  167.                     if (command == debugMessage)
  168.                         *destStringPtr++ = '"';
  169.                 }
  170.                 blockPointer->command = executeCommand;
  171.             }
  172.             if (waitForCompletion) {
  173.                 while (blockPointer->status) {
  174.                     if (lastToggle != blockPointer->toggle) {
  175.                         lastToggle = blockPointer->toggle;
  176.                         idleCount = 0;
  177.                     } else {
  178.                         idleCount++;
  179.                         if (idleCount > maximumIdle)
  180.                             return false;
  181.                     }
  182.                     EventAvail(everyEvent, &theEvent);
  183.                 }
  184.             }
  185.         } else
  186.             return false;
  187.     }
  188. #endif
  189.     return true;
  190. }
  191.  
  192. static boolean SendGraphicsBugMessage(const char *str, long message, long reference)
  193. {
  194.     reference = 0;  /* so MPW will not complain */
  195.     if (SendMessageToGraphicsBug(debugMessage, str, message, true) == false) {
  196.         GXSetUserGraphicsDebug(nil, 0);
  197.         return false;
  198.     }
  199.     return true;
  200. }
  201.  
  202. void DirectDebugMessageToGraphicsBug(void)
  203. {
  204.     GXSetUserGraphicsDebug(SendGraphicsBugMessage, 0);
  205. }
  206.